; ///// Z Axis Motion Test /////
; Moves Z between 10mm and 420mm continuously.
; Hold X or U endstop to stop (checked every ~0.5s).

; ---- Introduction ----
var introMsg = "Z axis will cycle between 10mm and 420mm.<br><br>"
set var.introMsg = var.introMsg ^ "Hold <b>X or U endstop</b> to stop the test."
M291 R"Z Motion Test" P{var.introMsg} S4 K{"Start Test","Cancel"}
if input == 1
  abort "Z motion test cancelled by user"

; ---- Homing Check ----
if !move.axes[0].homed || !move.axes[1].homed || !move.axes[2].homed || !move.axes[3].homed
  M291 R"Homing Required" P"All axes must be homed first.<br>Home all axes now?" S4 K{"Home All","Cancel"}
  if input == 1
    abort "Z motion test cancelled — axes not homed"
  G28

; ---- Initialize ----
var zMin = 10
var zMax = 420
var step = 10                                                                                 ; Segment size (mm) — endstop checked between segments
var goingUp = true
var cycleCount = 0
var zTarget = var.zMin
var stopped = false

G90                                                                                           ; Absolute positioning
G1 Z{var.zMin} F1200                                                                          ; Move to start position
M400                                                                                          ; Wait for move to complete

M291 R"Z Motion Test" P"Running... Hold X or U endstop to stop." S1 T0                       ; Persistent status message

; ---- Main Loop ----
while iterations < 500000 && !var.stopped
  ; Calculate next segment target
  if var.goingUp
    set var.zTarget = min(var.zTarget + var.step, var.zMax)
  else
    set var.zTarget = max(var.zTarget - var.step, var.zMin)

  G1 Z{var.zTarget} F1200
  M400

  ; Check endstop after each segment
  if sensors.endstops[0].triggered || sensors.endstops[3].triggered
    ; Move to safe position away from extremes
    if var.zTarget > 320
      G1 Z{var.zTarget - 100} F1200
    elif var.zTarget < 110
      G1 Z{var.zTarget + 100} F1200
    M400

    M292                                                                                      ; Dismiss status message
    M291 R"Z Motion Test" P{"Endstop pressed after " ^ var.cycleCount ^ " cycles.<br>Stop the test?"} S4 K{"Stop","Continue"}
    if input == 0
      set var.stopped = true
    else
      M291 R"Z Motion Test" P"Running... Hold X or U endstop to stop." S1 T0                 ; Re-show status

  ; Reverse direction at extremes
  if var.goingUp && var.zTarget >= var.zMax
    set var.goingUp = false
  elif !var.goingUp && var.zTarget <= var.zMin
    set var.goingUp = true
    set var.cycleCount = var.cycleCount + 1

; ---- Cleanup ----
M292                                                                                          ; Dismiss any remaining message
M291 R"Z Motion Test" P{"Completed " ^ var.cycleCount ^ " cycles."} S2

; ///// End of Z Motion Test /////
